#include "Settings.h"

#include "Output.h"
//#include "ParFile.h"

Settings::Settings()
{
}

Settings::~Settings()
{
}

bool Settings::readConfig(std::string fileName){
	
//	
//	/* We cannot use the nice getopt_long here, because it may permute the argv array */
//	/* See if any config file name was given */
//	/*std::string currentArg;
//	for (int i = 0; i < argc; ++i){
//		currentArg.assign(argv[i]);
//		if (currentArg.compare("-c") == 0 || currentArg.compare("--config-file") == 0){
//			if(i + 1 < argc) { //check if this is not the last command line argument
//				if(argv[i+1][0] != '-'){ //check if an actual value from the file name was provided
//					configFileName.assign(argv[i+1]);
//				}
//			}
//			break;
//		}
//	}*/
//	
//	
//	/**
//	 * use the ParFile class written by Stefan Hahne.
//	 * Config files according to this class are structured like this:
//	 * 
//	 * [Section Name]
//	 * 
//	 * OptionName = OptionValue
//	 * AnotherOptionName = "A quoted string value"
//	 * 
//	 * [Another Section]
//	 * 
//	 * #this is a comment telling you that whitespace is permitted
//	 * Option name with whitespace = 5
//	 * 
//	 * ---------
//	 * 
//	 * You can access these values through the method GetValue:
//	 * 
//	 * ParFile* parFile = newParFile("config.txt");
//	 * char* optionValue = parFile->GetValue("Section Name", "OptionName");
//	 * 
//	 * The method returns a C-Style string (use atoi/atof/etc for numerical values),
//	 * or NULL if the option is not present.
//	 **/
//	ParFile* configFile = new ParFile(fileName.c_str());
//	
//	if(configFile->isOpen()){ //check if there is any config file
//		
//		char* value = NULL;
//		
//		/* == General settings === */
//		if((value = configFile->GetValue("General","Trade memory for speed")) != NULL) {
//			std::string valueString = value;
//			
//			if (valueString.compare("YES") == 0){
//	           tradeMemoryForSpeed = true;
//	        } else if (valueString.compare("TRUE") == 0){
//	            tradeMemoryForSpeed = true;
//	        } else if (valueString.compare("1") == 0){
//	        	tradeMemoryForSpeed = true;
//	        } else if (valueString.compare("NO") == 0){
//	            tradeMemoryForSpeed = false;
//	        } else if (valueString.compare("FALSE") == 0){
//	            tradeMemoryForSpeed = false;
//	        } else if (valueString.compare("0") == 0){
//	            tradeMemoryForSpeed = false;
//	        } else {
//	            Output::message("Unknown value \"%s\" for Memory option, defaulting to \"FALSE\"", Output::CRITICAL, valueString.c_str());
//	            tradeMemoryForSpeed = false;
//	        }
//		}
//		
//		/* === Output settings === */ 
//		if((value = configFile->GetValue("Output","DebugLevel")) != NULL) { //assign value and check for existence
//	        std::string valueString = value;
//	        
//	        if (valueString.compare("DEBUG") == 0){
//	            debugLevel = Output::DEBUG;
//	        } else if (valueString.compare("TESTING") == 0){
//	            debugLevel = Output::TESTING;
//	        } else if (valueString.compare("VERBOSE") == 0){
//	            debugLevel = Output::VERBOSE;
//	        } else if (valueString.compare("IMPORTANT") == 0){
//	            debugLevel = Output::IMPORTANT;
//	        } else if (valueString.compare("CRITICAL") == 0){
//	            debugLevel = Output::CRITICAL;
//	        } else if (valueString.compare("QUIET") == 0){
//	            debugLevel = Output::QUIET;
//	        } else {
//	            Output::message("Unknown Output Level \"%s\", defaulting to \"VERBOSE\"", Output::CRITICAL, valueString.c_str());
//	            debugLevel = Output::VERBOSE;
//	            valueString = "VERBOSE";
//	        }
//	        
//	        Output::setOutputLevel(debugLevel);
//	        debugLevelName = valueString;
//	        
//	        if (debugLevel  >= Output::VERBOSE){
//	        	Output::showFunctionNames(false);
//	        }
//	        
//	    }
//		
//		if((value = configFile->GetValue("Output","Save Images")) != NULL) {
//			std::string valueString = value;
//			
//			if (valueString.compare("YES") == 0){
//	           saveImages = true;
//	        } else if (valueString.compare("TRUE") == 0){
//	            saveImages = true;
//	        } else if (valueString.compare("1") == 0){
//	        	saveImages = true;
//	        } else if (valueString.compare("NO") == 0){
//	            saveImages = false;
//	        } else if (valueString.compare("FALSE") == 0){
//	            saveImages = false;
//	        } else if (valueString.compare("0") == 0){
//	            saveImages = false;
//	        } else {
//	            Output::message("Unknown value \"%s\" for images save option, defaulting to \"TRUE\"", Output::CRITICAL, valueString.c_str());
//	            saveImages = true;
//	        }
//		}
//		
//		if((value = configFile->GetValue("Output","Show Images")) != NULL) {
//			std::string valueString = value;
//			
//			if (valueString.compare("YES") == 0){
//	           showImages = true;
//	        } else if (valueString.compare("TRUE") == 0){
//	            showImages = true;
//	        } else if (valueString.compare("1") == 0){
//	        	showImages = true;
//	        } else if (valueString.compare("NO") == 0){
//	            showImages = false;
//	        } else if (valueString.compare("FALSE") == 0){
//	            showImages = false;
//	        } else if (valueString.compare("0") == 0){
//	            showImages = false;
//	        } else {
//	            Output::message("Unknown value \"%s\" for show images option, defaulting to \"TRUE\"", Output::CRITICAL, valueString.c_str());
//	            showImages = true;
//	        }
//		}
//		
//		if((value = configFile->GetValue("Output","Show Features")) != NULL) {
//			std::string valueString = value;
//			
//			if (valueString.compare("YES") == 0){
//	           showFeatures = true;
//	        } else if (valueString.compare("TRUE") == 0){
//	            showFeatures = true;
//	        } else if (valueString.compare("1") == 0){
//	        	showFeatures = true;
//	        } else if (valueString.compare("NO") == 0){
//	            showFeatures = false;
//	        } else if (valueString.compare("FALSE") == 0){
//	            showFeatures = false;
//	        } else if (valueString.compare("0") == 0){
//	            showFeatures = false;
//	        } else {
//	            Output::message("Unknown value \"%s\" for show features option, defaulting to \"TRUE\"", Output::CRITICAL, valueString.c_str());
//	            showFeatures = true;
//	        }
//		}
//
//		if((value = configFile->GetValue("Output","Show Correlation")) != NULL) {
//			std::string valueString = value;
//			
//			if (valueString.compare("YES") == 0){
//	           showCorrelation = true;
//	        } else if (valueString.compare("TRUE") == 0){
//	            showCorrelation = true;
//	        } else if (valueString.compare("1") == 0){
//	        	showCorrelation = true;
//	        } else if (valueString.compare("NO") == 0){
//	            showCorrelation = false;
//	        } else if (valueString.compare("FALSE") == 0){
//	            showCorrelation = false;
//	        } else if (valueString.compare("0") == 0){
//	            showCorrelation = false;
//	        } else {
//	            Output::message("Unknown value \"%s\" for show correlation option, defaulting to \"TRUE\"", Output::CRITICAL, valueString.c_str());
//	            showCorrelation = true;
//	        }
//		}
//		
//		if(!showImages){
//			showFeatures = false;
//			showCorrelation = false;
//		}
//		
//		
//		/* === Feature Detection settings === */
//		if((value = configFile->GetValue("FeatureDetection", "Max Feature Points")) != NULL){
//	        maxFeaturePoints = atoi(value);
//	    }
//		
//		
//	        
//		/* === Correlation Settings === */
//		if((value = configFile->GetValue("Correlation", "Neighborhood")) != NULL){
//	        correlationNeighborhood = atoi(value);
//	    }
//		if((value = configFile->GetValue("Correlation", "VNC Threshold")) != NULL){
//	        correlationVNCThreshold = atof(value);
//	    }
//		if((value = configFile->GetValue("Correlation", "Max Image Overlap")) != NULL){
//	        maxImageOverlap = atof(value);
//	    }
//		
//		/* === RANSAC Settings for homography determination === */
//		if((value = configFile->GetValue("RANSAC", "Iterations")) != NULL){
//	        ransacNumOfIterations = atoi(value);
//	    }
//		if((value = configFile->GetValue("RANSAC", "Homography Samples")) != NULL){
//	        ransacNumOfMaybeInliers = atoi(value);
//	    }
//		if((value = configFile->GetValue("RANSAC", "Tolerated Error")) != NULL){
//	        ransacInliersToleratedError = atof(value);
//	    }
//		if((value = configFile->GetValue("RANSAC", "Early Exit Threshold")) != NULL){
//	        ransacStopIterationAtPercentageOfMatches = atof(value);
//	    }
//		if((value = configFile->GetValue("RANSAC", "Minimum Supporters")) != NULL){
//	        ransacMinNumOfSupporters = atoi(value);
//	    }
//
//	} else {
//		return false;
//	}
//	
//	delete configFile;
//	
	return true;
}


void Settings::printConfig(int atDebugLevel) {
	
	Output::separator("", atDebugLevel);
	Output::message("Current configuration:", atDebugLevel);
	
	Output::message("[Output]", atDebugLevel);
	Output::message("DebugLevel: %s", atDebugLevel, Settings::debugLevelName.c_str());
	Output::message("Save Images: %d", atDebugLevel, Settings::saveImages);
	Output::message("Show Images: %d", atDebugLevel, Settings::showImages);
	Output::message("Show Features: %d", atDebugLevel, Settings::showFeatures);
	Output::message("Show Correlation: %d", atDebugLevel, Settings::showCorrelation);
	Output::separator("", atDebugLevel);
	
	
	Output::message("[Correlation]", atDebugLevel);
	Output::message("Neighborhood: %d", atDebugLevel, correlationNeighborhood);
	Output::message("VNC Threshold: %f", atDebugLevel, correlationVNCThreshold);
	
	
}


bool Settings::saveImages = true;
bool Settings::showFeatures = true;
bool Settings::showCorrelation = true;
bool Settings::showImages = true;

int Settings::correlationNeighborhood = 3;
double Settings::correlationVNCThreshold = 0.83;
double Settings::maxImageOverlap = 0.52;
int Settings::debugLevel = Output::TESTING;

int Settings::horizontalGridPoints = 10;
int Settings::verticalGridPoints = 8;

int Settings::pyramidalDepth = 5;

std::string Settings::featureDetectionTypeName = "Simple";
std::string Settings::debugLevelName = "DEBUG";

unsigned int Settings::ransacMinNumOfSupporters = 4;
int Settings::maxFeaturePoints = 300;

